namespace SimpleWebServices.Data
{
    using System;
    using SimpleWebServices;
    using Xunit;

    public sealed class TokenFacts
    {
        [Fact]
        public void typedef()
        {
            Assert.True(new ObjectExpectations<Token>()
                .IsValueType()
                .Result);
        }

        [Fact]
        public void ctor()
        {
            Assert.NotNull(new Token());
        }

        [Fact]
        public void ctor_Guid()
        {
            Assert.NotNull(new Token(Guid.NewGuid()));
        }

        [Fact]
        public void ctor_string()
        {
            Assert.NotNull(new Token(Guid.NewGuid().ToString()));
        }

        [Fact]
        public void ctor_stringEmpty()
        {
            Assert.NotNull(new Token(string.Empty));
        }

        [Fact]
        public void ctor_stringNull()
        {
            Assert.Throws<ArgumentNullException>(() => new Token(null));
        }

        [Fact]
        public void prop_Empty()
        {
            Token expected = Guid.Empty;
            Token actual = Token.Empty;

            Assert.Equal<Token>(expected, actual);
        }

        [Fact]
        public void prop_IsEmpty_true()
        {
            Assert.True(new Token(Guid.Empty).IsEmpty);
        }

        [Fact]
        public void prop_IsEmpty_false()
        {
            Assert.False(new Token(Guid.NewGuid()).IsEmpty);
        }

        [Fact]
        public void opEquality_Token_Token()
        {
            Guid value = Guid.NewGuid();

            Token obj = new Token(value);
            Token comparand = new Token(value);

            Assert.True(obj == comparand);
        }

        [Fact]
        public void opEquality_Token_TokenDiffers()
        {
            Assert.False(Guid.NewGuid() == Guid.NewGuid());
        }

        [Fact]
        public void opImplicit_Token_Guid()
        {
            Guid value = Guid.NewGuid();
            Token expected = new Token(value);
            Token actual = value;

            Assert.Equal<Token>(expected, actual);
        }

        [Fact]
        public void opImplicit_Guid_Token()
        {
            Guid expected = Guid.NewGuid();
            Guid actual = new Token(expected);

            Assert.Equal<Guid>(expected, actual);
        }

        [Fact]
        public void opImplicit_Token_string()
        {
            string value = Guid.NewGuid().ToString();
            Token expected = new Token(value);
            Token actual = value;

            Assert.Equal<Token>(expected, actual);
        }

        [Fact]
        public void opImplicit_string_Token()
        {
            string expected = Guid.NewGuid().ToString();
            string actual = new Token(expected);

            Assert.Equal<string>(expected, actual);
        }

        [Fact]
        public void opInequality_Token_Token()
        {
            Guid value = Guid.NewGuid();

            Token obj = new Token(value);
            Token comparand = new Token(value);

            Assert.False(obj != comparand);
        }

        [Fact]
        public void opInequality_Token_TokenDiffers()
        {
            Assert.True(Guid.NewGuid() != Guid.NewGuid());
        }

        [Fact]
        public void op_New()
        {
            Assert.NotEqual<Token>(Token.Empty, Token.New());
        }

        [Fact]
        public void op_ToGuid()
        {
            Guid expected = Guid.NewGuid();
            Guid actual = new Token(expected).ToGuid();

            Assert.Equal<Guid>(expected, actual);
        }

        [Fact]
        public void op_Equals_object()
        {
            Guid value = Guid.NewGuid();

            Token obj = new Token(value);
            Token comparand = new Token(value);

            Assert.True(obj.Equals(comparand as object));
        }

        [Fact]
        public void op_Equals_objectDiffers()
        {
            Token obj = Guid.NewGuid();
            Token comparand = Guid.NewGuid();

            Assert.False(obj.Equals(comparand as object));
        }

        [Fact]
        public void op_Equals_objectNull()
        {
            Assert.False(Guid.NewGuid().Equals(null as object));
        }

        [Fact]
        public void op_Equals_objectSame()
        {
            Token obj = Guid.NewGuid();

            Assert.True(obj.Equals(obj as object));
        }

        [Fact]
        public void op_Equals_objectString()
        {
            Guid value = Guid.NewGuid();

            Assert.False(new Token(value).Equals(value.ToString() as object));
        }

        [Fact]
        public void op_ToString()
        {
            string expected = Guid.Empty.ToString();
            string actual = new Token().ToString();

            Assert.Equal<string>(expected, actual);
        }

        [Fact]
        public void op_GetHashCode()
        {
            int expected = Guid.Empty.GetHashCode();
            int actual = new Token().GetHashCode();

            Assert.Equal<int>(expected, actual);
        }
    }
}